#pragma once
#include <chrono>
#include <iomanip>
#include <iostream>
#include <optional>
#include <string>

namespace cem
{

// 类: SimpleTimer
// 作用: 提供简单的起止计时与当前耗时查询，适用于代码片段的性能统计。
// 使用方法:
//   SimpleTimer t; t.start(); ... 代码 ... double sec = t.stop_seconds();
class SimpleTimer
{
public:
    // 函数: SimpleTimer
    // 作用: 默认构造，计时器处于未运行状态。
    // 参数: 无
    // 返回: 无
    SimpleTimer() = default;

    // 函数: start
    // 作用: 开始计时，若已在运行则重置起点。
    // 参数: 无
    // 返回: 无
    void start()
    {
        _start_time = std::chrono::steady_clock::now();
        _running = true;
        _last_elapsed_seconds = 0.0;
    }

    // 函数: stop_seconds
    // 作用: 停止计时并返回以秒为单位的耗时。
    // 参数: 无
    // 返回: double, 耗时秒数
    double stop_seconds()
    {
        if (_running)
        {
            _stop_time = std::chrono::steady_clock::now();
            _running = false;
            _last_elapsed_seconds =
                std::chrono::duration<double>(_stop_time - _start_time).count();
        }
        return _last_elapsed_seconds;
    }

    // 函数: stop_milliseconds
    // 作用: 停止计时并返回以毫秒为单位的耗时。
    // 参数: 无
    // 返回: double, 耗时毫秒数
    double stop_milliseconds()
    {
        return stop_seconds() * 1000.0;
    }

    // 函数: elapsed_seconds
    // 作用: 查询当前耗时（若仍在运行则以“当前时间-起点”，若已停止则返回上次停止时的耗时）。
    // 参数: 无
    // 返回: double, 耗时秒数
    double elapsed_seconds() const
    {
        if (_running)
        {
            auto now = std::chrono::steady_clock::now();
            return std::chrono::duration<double>(now - _start_time).count();
        }
        return _last_elapsed_seconds;
    }

    // 函数: elapsed_milliseconds
    // 作用: 查询当前耗时（毫秒）。
    // 参数: 无
    // 返回: double, 耗时毫秒数
    double elapsed_milliseconds() const
    {
        return elapsed_seconds() * 1000.0;
    }

    // 函数: reset
    // 作用: 重置计时器到初始状态（未运行，耗时为 0）。
    // 参数: 无
    // 返回: 无
    void reset()
    {
        _running = false;
        _last_elapsed_seconds = 0.0;
    }

    // 函数: is_running
    // 作用: 查询计时器是否在运行。
    // 参数: 无
    // 返回: bool, true 表示正在计时
    bool is_running() const { return _running; }

private:
    std::chrono::steady_clock::time_point _start_time{};
    std::chrono::steady_clock::time_point _stop_time{};
    bool _running{false};
    double _last_elapsed_seconds{0.0};
};

// 类: TimerScope
// 作用: 作用域计时器（RAII）。构造时开始计时，析构时自动打印耗时。
// 使用方法:
//   {
//       TimerScope scope("assemble");
//       ... 被测代码 ...
//   } // 退出作用域时打印: [timer] assemble: 12.34 ms (0.01234 s)
class TimerScope
{
public:
    // 函数: TimerScope
    // 作用: 创建作用域计时器并立即开始计时。
    // 参数:
    //   label: 打印时使用的标识文本
    //   stream: 可选输出流，默认输出到 std::cout
    // 返回: 无
    explicit TimerScope(std::string label, std::ostream * stream = nullptr)
        : _label(std::move(label)), _stream(stream ? stream : &std::cout)
    {
        _timer.start();
    }

    // 函数: ~TimerScope
    // 作用: 析构时停止计时并输出格式化结果。
    // 参数: 无
    // 返回: 无
    ~TimerScope()
    {
        const double sec = _timer.stop_seconds();
        const double ms = sec * 1000.0;
        (*_stream) << "[timer] " << _label << ": "
                   << std::fixed << std::setprecision(3) << ms << " ms ("
                   << std::setprecision(6) << sec << " s)" << std::endl;
    }

    // 函数: elapsed_seconds
    // 作用: 查询当前耗时（秒）。
    // 参数: 无
    // 返回: double, 耗时秒数
    double elapsed_seconds() const { return _timer.elapsed_seconds(); }

    // 函数: elapsed_milliseconds
    // 作用: 查询当前耗时（毫秒）。
    // 参数: 无
    // 返回: double, 耗时毫秒数
    double elapsed_milliseconds() const { return _timer.elapsed_milliseconds(); }

private:
    SimpleTimer _timer{};
    std::string _label{};
    std::ostream * _stream{&std::cout};
};

} // namespace cem